import { useMutation } from "@apollo/client";
import {
  Drawer,
  Input,
  Button,
  Image,
  Select,
  Divider,
  Tooltip,
  message,
  Spin,
  Form,
} from "antd";
import { findIndex, map, remove, trim } from "lodash";
import { useState, forwardRef, useImperativeHandle, useEffect } from "react";
import { useLocation } from "react-router-dom";

import U3400 from "../../assets/imgs/u3400.svg";
import U3401 from "../../assets/imgs/u3401.svg";
import U3402 from "../../assets/imgs/u3402.svg";
import U3403 from "../../assets/imgs/u3403.svg";
import U3405 from "../../assets/imgs/u3405.svg";
import U3406 from "../../assets/imgs/u3406.svg";
import U3407 from "../../assets/imgs/u3407.svg";
import U3408 from "../../assets/imgs/u3408.svg";
import U3409 from "../../assets/imgs/u3409.svg";
import U3410 from "../../assets/imgs/u3410.svg";
import U3411 from "../../assets/imgs/u3411.svg";
import U3412 from "../../assets/imgs/u3412.svg";
import U3413 from "../../assets/imgs/u3413.svg";
import U3414 from "../../assets/imgs/u3414.svg";
import { Obj } from "./index";

import { useAnalysisTask } from "~/components/Visualization/store/useTaskState";
import {
  getCustomParamUT,
  getCustomParamDocument,
} from "~/hooks/Visualization/use-visualization-api";
// import { Mutation } from "~/modules/api-server/types";
import {
  MutationParamsArgs,
  ActType,
  Mutation,
} from "~/modules/api-server/types2";
import { useWorkSpace } from "~/modules/workspace/store/use-workspace";
import { getContent } from "~/plugins/api-server";
import eventBus from "~/utils/event";

const { TextArea } = Input;

interface Props {
  param: { type: string; value?: any };
}
// 计算方法
const operator: any[] = [
  { value: "+", label: U3400, title: "加法" },
  { value: "-", label: U3401, title: "减法" },
  { value: "*", label: U3402, title: "乘法" },
  { value: "/", label: U3403, title: "除法" },
  { value: "==", label: U3405, title: "等于" },
  { value: "!=", label: U3406, title: "不等于" },
  { value: "<", label: U3410, title: "小于" },
  { value: ">", label: U3409, title: "大于" },
  { value: "<=", label: U3407, title: "小于等于" },
  { value: ">=", label: U3408, title: "大于等于" },
  { value: "(", label: U3412, title: "左括号" },
  { value: ")", label: U3411, title: "右括号" },
  { value: "&&", label: U3413, title: "逻辑与" },
  { value: "||", label: U3414, title: "逻辑或" },
];
interface ResultsList {
  result: number[];
  [x: string]: number[];
}
const CustomParameters = (props: Props, ref: any) => {
  // 获取路由传参
  const location = useLocation();
  // 获取task信息
  const { analysisTask, updateTask } = useAnalysisTask();
  // 抽屉的显示隐藏
  const [isOpen, setIsOpen] = useState<boolean>(false);
  // 自定义参数名称
  const [paramsName, setParamseName] = useState<string>("");
  // 计算表达式
  const [textInput, setTextInput] = useState<string>("");
  // 飞行ids
  const { flights } = useWorkSpace();
  // 数据加载状态
  const [isLoading, setIsLoading] = useState<boolean>(false);
  // 是否提交自定义参数
  const [isSubmitBtn, setIsSubmitBtn] = useState<boolean>(true);
  const [utResultsList, setUtResultsList] = useState<ResultsList>({
    N1: [],
    N2: [],
    result: [],
  });
  // 操作的参数
  const [operationParams, setOperationParams] = useState<string[]>([]);

  // 创建、更新自定义参数
  const [addOrEditCustomParam, { data: addOrEditData }] = useMutation<
    Mutation,
    MutationParamsArgs
  >(getCustomParamDocument, {
    client: getContent().explorer_apiServer,
  });
  useEffect(() => {
    if (addOrEditData) {
      const task = {
        id: addOrEditData?.Params.id,
        name: paramsName,
        desc: "",
        expression: textInput,
      };
      if (props.param.type === "add") {
        analysisTask.customParams.push(task);
      } else {
        const num: number = findIndex(analysisTask.customParams, (item) => {
          return item.name === props.param.value.name;
        });
        analysisTask.customParams.splice(num, 1);
        updateTask(analysisTask);
        analysisTask.customParams.push(task);
      }
      updateTask(analysisTask);
      setParamseName("");
      setTextInput("");
      setUtResultsList({
        result: [],
      });
      setOperationParams([]);
      setIsOpen(false);
      setIsSubmitBtn(true);
    }
  }, [addOrEditData]);
  //
  const [form] = Form.useForm();
  // 参数列表
  const [paramsOptions, setParamsOptions] = useState<any[]>([]);

  useEffect(() => {
    eventBus.on(`flightParamsList`, (value: any) => {
      const data: any[] = map(value, (t) => {
        return {
          label: t.name,
          options: map(t.params, (k) => {
            return { label: k.name, value: k.name };
          }),
        };
      });
      setParamsOptions(data);
    });
    if (props.param.type === "edit" && isOpen) {
      setParamseName(props.param.value?.name);
      setTextInput(props.param.value?.expression);
    }
  }, [isOpen]);
  useEffect(() => {
    form.validateFields(["name"]);
  }, [form]);
  // 计算参数操作方法HTML
  const calculationHead = (
    <div className="h-40px flex justify-between bg-#EFF4FB">
      <div className="flex">
        <Select
          showSearch
          placeholder="选择参数"
          optionFilterProp="label"
          size="large"
          style={{ width: "260px" }}
          options={paramsOptions}
          onChange={(e) => onParamsChange(e)}
        />
        <Divider className="h-32px! mt-4px! ml-10px!" type="vertical" />
        <div className="flex">
          {operator.map((item: Obj, index: number) => {
            return (
              <Tooltip key={index} title={item.title}>
                <Button
                  type="text"
                  style={{ width: "40px", height: "40px" }}
                  onClick={() => onOperator(item.value)}
                >
                  <Image
                    width={13}
                    height={17}
                    preview={false}
                    src={item.label}
                  />
                </Button>
              </Tooltip>
            );
          })}
        </div>
      </div>
      <Button
        className="h-40px! font-700! bg-#84afeb!"
        type="text"
        disabled={textInput.length === 0 || paramsName.length === 0}
        onClick={() => onTest()}
      >
        测试
      </Button>
    </div>
  );

  //  选择参数
  const onParamsChange = (params: string) => {
    // operationParams.push(params);
    const data = textInput + `[${params}]`;
    setTextInput(data);
  };

  // 运算符
  const onOperator = (value: string) => {
    const data = textInput + value;
    setTextInput(data);
  };

  // 单元测试
  const onTest = async () => {
    setIsLoading(true);
    const data = {
      flightIds: flights,
      expression: textInput,
    };
    const UtRes = await getCustomParamUT(data);
    const UtResData = UtRes?.data?.data;
    if (UtResData?.code === "success") {
      setIsSubmitBtn(false);
      setUtResultsList(UtResData?.data);
      const arr: any = Object.keys(UtResData?.data);
      setOperationParams(arr);
    } else {
      message.error(UtResData?.msg ?? "计算参数测试失败！");
    }
    setIsLoading(false);
  };
  // 自定义参数计算结果HTML
  const resultsDiv = map(
    Object.keys(utResultsList),
    (item: string, index: number) => {
      return (
        <div key={index} className="flex-1">
          {map(utResultsList[item], (k: number, i: number) => {
            return (
              <p
                key={i}
                className="h-40px text-center m-0 custom-param-results-content-item"
              >
                {k}
              </p>
            );
          })}
        </div>
      );
    }
  );

  // 取消
  const onCancel = () => {
    setParamseName("");
    setTextInput("");
    setUtResultsList({
      result: [],
    });
    setOperationParams([]);

    setIsSubmitBtn(true);
    setIsOpen(false);
  };

  // 确定
  const onDefine = () => {
    const params: any[] = [
      ...analysisTask.taskParams,
      ...analysisTask.customParams,
    ];
    if (props.param.type === "edit") {
      remove(params, (item) => {
        return item.name === paramsName;
      });
    }

    const num: number = findIndex(params, (item) => {
      return item.name === paramsName;
    });
    if (paramsName.length === 0) {
      message.error("请输入参数名称！");
    } else if (num !== -1) {
      message.error("该参数名称已存在！");
    } else {
      const param = {
        id: props.param.type === "add" ? "" : props.param.value.id,
        tid: analysisTask.id,
        name: paramsName,
        desc: "",
        expression: textInput,
        act_type: props.param.type === "add" ? ActType.Create : ActType.Update,
      };
      addOrEditCustomParam({
        variables: {
          input: param,
        },
      });
    }
  };

  // 打开抽屉
  const onOpen = () => {
    setIsOpen(true);
  };

  // 关闭抽屉
  const onClose = () => {
    setIsOpen(false);
  };

  // 向父组件暴露关闭抽屉方法
  useImperativeHandle(ref, () => ({
    onOpen,
  }));

  return (
    <div>
      <Drawer
        title="添加自定义计算列"
        placement="right"
        width="74%"
        closable={false}
        destroyOnClose
        onClose={onClose}
        open={isOpen}
      >
        <Spin tip="Loading..." spinning={isLoading}>
          <Form form={form} name="dynamic_rule">
            <Form.Item
              name="name"
              rules={[
                { required: true, message: "自定义参数名称为必填项" },
                { pattern: /^[^\s]*$/, message: "禁止输入空格" },
              ]}
            >
              <Input
                className="mb-16px!"
                value={paramsName}
                placeholder="请输入自定义参数名称"
                onChange={(e) => setParamseName(trim(e.target.value))}
              />
            </Form.Item>
          </Form>
          <div>
            {calculationHead}
            <TextArea
              className="p-16px!"
              value={textInput}
              onChange={(e) => setTextInput(e.target.value)}
              autoSize={{ minRows: 5, maxRows: 5 }}
            />
          </div>
          <Divider className="mt-16px! mb-16px!" dashed />
          <div
            className="flex h-32px text-center color-#9B9FA6 bg-#EFF4FB"
            style={{ lineHeight: "32px" }}
          >
            {operationParams.map((item: string, index: number) => {
              return (
                <div className="custom-param-results-head-item" key={index}>
                  {item}
                </div>
              );
            })}
          </div>
          <div className="flex">{resultsDiv}</div>

          <div className="flex justify-end mt-6">
            <Button className="w-96px mr-16px" onClick={() => onCancel()}>
              取消
            </Button>
            <Button
              className="w-96px"
              type="primary"
              disabled={isSubmitBtn}
              onClick={() => onDefine()}
            >
              确定
            </Button>
          </div>
        </Spin>
      </Drawer>
    </div>
  );
};

export default forwardRef(CustomParameters);
